package com.demo.lengthFieldBasedFrameDecoder.custom;

import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * 1 魔数
 * 2 版本号
 *
 *
 */
public class MessageCodec extends ByteToMessageCodec<Message> {

    private Logger log = LoggerFactory.getLogger(MessageCodec.class);


    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
          //字节设计一般2的整数倍

           //1四个字节的魔数
           out.writeBytes(new byte[]{1,2,3,4});
           //2版本
           out.writeByte(1);
           //3序列化方式,0 jdk,1json
           out.writeByte(0);
           //4 字节的额指令类型 0 login 2 聊天类型
           out.writeByte(0); //理论上message 里面有个messagetype呢
           //5,4个字节序列号
           out.writeInt(msg.getSequenceId());

           out.writeByte(0xff);//对其填充用

           //6 获取内容的字节数组
        ByteOutputStream bos = new ByteOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(msg);
        byte[] databytes = bos.toByteArray();

        //7 设置长度
        out.writeInt(databytes.length);
        out.writeBytes(databytes);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        byte seqType  = in.readByte();//序列化方式
        byte messageType  = in.readByte();
        int seqId = in.readInt();
        in.readByte();

        //读取数据长度
        int length  =  in.readInt();
         byte[] bytes = new byte[length];
         in.readBytes(bytes,0,length);

         if(seqType == 0){
             //jdk的反序列化方式呢
             ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
             Message message = (Message) ois.readObject();
             System.out.println("message==="+message.getSequenceId());
             log.info("decode:{},{},{},{},{},{}",magicNum,version,seqType,messageType,seqId,length);
             out.add(message);
         }
    }
}
